from pathlib import Path

from flask import abort, jsonify, send_from_directory, request, send_file, make_response, url_for, current_app
from flask_restful import Resource, reqparse
import os

from project_name.models import accounts, db
from project_name.base import Admin_DIR, User_DIR, source_file
import pandas as pd

from project_name.utils import get_real_path, excel_default_column, get_image_features, get_patient_diagnosis, \
    get_child_folders, get_child_file_list, get_image_feature, replace_list


class AddUserResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('adminId', type=str, required=True, help='adminId is required')
        parser.add_argument('username', type=str, required=True, help='username is required')
        parser.add_argument('realName', type=str, required=True, help='realName is required')
        parser.add_argument('password', type=str, required=True, help='password is required')
        data = parser.parse_args()

        if accounts.query.filter_by(username=data["username"]).first():
            return jsonify({"code": 404, "message": "用户已存在", "data": ""})

        new_user = accounts(
            username=str(data["username"]),
            real_name=str(data["realName"]),
            password=str(data["password"]),
            id_type=1,
            parent_account_id=str(data["adminId"])
        )
        print("new_user", new_user)
        db.session.add(new_user)
        db.session.commit()

        return jsonify({"code": 200, "message": "用户添加成功", "data": new_user.to_dict()})


class UpdateUserResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('username', type=str, required=True, help='username is required')
        parser.add_argument('realName', type=str, required=True, help='realName is required')
        data = parser.parse_args()

        user = accounts.query.filter_by(username=data["username"]).first()
        if user:
            user.real_name = data["realName"]
            db.session.commit()
            return jsonify({"code": 200, "message": "成功", "data": data})
        return jsonify({"code": 404, "message": "编辑失败", "data": data})


class DeleteUserResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('delete_id', type=str, required=True, help='delete_id is required')
        data = parser.parse_args()

        user = accounts.query.get(data["delete_id"])
        if user:
            db.session.delete(user)
            db.session.commit()
            return jsonify({"code": 200, "message": "成功"})
        return jsonify({"code": 404, "message": "User not found"})


class SearchResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('username', type=str, required=True, help='username is required')
        data = parser.parse_args()

        transformed_data = []
        result = []
        if data['username'] == "":
            results = accounts.query.all()
        else:
            results = accounts.query.filter(accounts.username.ilike(f"%{data['username']}%")).all()
        for record in results:
            transformed_data.append({
                "id": record.id,
                "username": record.username,
                "realName": record.real_name,
                "parentId": record.parent_account_id,
                "createAt": record.created_at.strftime('%Y-%m-%d %H:%M:%S'),
                "idType": record.id_type
            })
        return jsonify({"code": 200, "data": transformed_data})


class GetUserFileListResource(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('username', type=str, required=True, help='username is required')
        data = parser.parse_args()

        try:
            full_path = os.path.join(User_DIR, data['username'])

            if not os.path.exists(full_path):
                return jsonify({"code": 400, "message": "用户还没有文件", "data": ""})

            file_list = []
            # 读取患者文件夹,并读取文件夹下的图片和excel文件
            for item in os.listdir(full_path):
                item_path = os.path.join(full_path, item)
                if os.path.isdir(item_path):
                    file_list.append({
                        "name": item,
                        "type": "directory"
                    })
            return {"code": 200, "message": "获取文件夹成功", "data": file_list}
        except Exception as e:
            return jsonify({"code": 400, "error": str(e), "data": ""})


class SaveAnnotationResource(Resource):
    def post(self):
        file_path = request.json['path']
        image_name = request.json['imageName']
        fields = request.json['fields']
        sys_path = get_real_path(file_path, ",")

        # 生成excel路径
        excel_name = file_path.split(",")[-1] + ".xlsx"
        excel_dir = os.path.join(current_app.static_folder, "User", sys_path)
        excel_path = os.path.join(excel_dir, excel_name)

        # 确保目录存在
        os.makedirs(excel_dir, exist_ok=True)

        # 如果excel不存在，就创建一个
        if not os.path.exists(excel_path):
            df = pd.DataFrame(columns=excel_default_column)
        else:
            df = pd.read_excel(excel_path)

        # 查找匹配的行
        mask = df['图片名称'] == image_name
        if mask.any():
            # 更新现有行 - 将每个字段的值设为True或1或其他适当的值
            df.loc[mask, excel_default_column[1:]] = 0  # 重置所有字段为0
            for s in replace_list:
                df.loc[mask, s] = 0  # 重置目标字段为0
            for field in fields:
                df.loc[mask, field] = 1  # 或者使用其他适当的值

        else:
            # 添加新行
            new_row = {'图片名称': image_name}
            # 初始化所有字段为0/False，然后设置指定的字段
            new_row.update({col: 0 for col in excel_default_column if col != '图片名称'})
            for field in fields:
                new_row[field] = 1  # 或者使用其他适当的值
            df = pd.concat([df, pd.DataFrame([new_row])], ignore_index=True)

        # 保存Excel
        df.to_excel(excel_path, index=False)

        return jsonify({"code": 200, "message": "保存成功"})


class SavePatientResource(Resource):
    def post(self):
        file_path = request.json['path']
        patient_name = request.json['patientName']
        diagnosis_result = request.json['diagnosisResult']
        sys_path = get_real_path(file_path, ",")

        # 生成excel路径
        excel_dir = os.path.join(current_app.static_folder, "User", sys_path)
        excel_path = os.path.join(excel_dir, patient_name+".xlsx")

        # 确保目录存在
        os.makedirs(excel_dir, exist_ok=True)
        df = pd.read_excel(excel_path)
        # 查找匹配的行
        mask = df['图片名称'] == "诊断结果"
        if mask.any():
            df[excel_default_column[1]] = df[excel_default_column[1]].astype(str)  # 先转换为字符串类型
            df.loc[mask, excel_default_column[1]] = diagnosis_result  # 再赋值
        else:
            # 添加新行
            new_row = {'图片名称': "诊断结果", "方向左侧": diagnosis_result}
            df = pd.concat([df, pd.DataFrame([new_row])], ignore_index=True)

        # 保存Excel
        df.to_excel(excel_path, index=False)

        return jsonify({"code": 200, "message": "保存成功"})


class GetPatientInfoListResource(Resource):
    """
    获取目标目录的患者信息
    """
    @staticmethod
    def post():
        parser = reqparse.RequestParser()
        parser.add_argument('path', type=str, required=True, help='path is required')
        data = parser.parse_args()

        # 获取患者文件夹列表
        path = get_real_path(data['path'], ",")
        path = Path(current_app.config['user_dir']) / path
        if not path.exists():
            return jsonify({"code": 400, "message": "文件夹不存在", "data": ""})
        folder_names = get_child_folders(path)
        if not folder_names:
            return jsonify({"code": 400, "message": "文件夹为空", "data": ""})
        # 获取患者报告excel信息
        patient_excel_path = ""
        for dir_name in path.iterdir():
            if dir_name.is_file() and dir_name.suffix.lower() == ".xlsx":
                patient_excel_path = dir_name
                # 只读取一个excel
                break
        if not patient_excel_path:
            return jsonify({"code": 400, "message": "没有找到患者报告Excel文件", "data": ""})

        # 读取excel文件
        patient_info = get_patient_diagnosis(patient_excel_path)
        # 组装返回数据
        result = []
        for patient_folder_name in folder_names:
            if patient_folder_name in patient_info.keys():
                result.append({
                    'name': patient_folder_name,
                    'checkingProcess': patient_info[patient_folder_name].get("checkingProcess"),
                    'diagnosis': patient_info[patient_folder_name].get("diagnosis"),
                })
        return jsonify({"code": 200, "message": "获取所有患者信息数据成功", "data": result})


class GetPatientInfoResource(Resource):
    """
    获取目标目录的目标患者信息
    """
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('path', type=str, required=True, help='path is required')
        parser.add_argument('patientName', type=str, required=True, help='patientName is required')
        data = parser.parse_args()

        # 获取患者文件夹路径
        patient_name = data['patientName']
        path = get_real_path(data['path'], ",")
        patient_path = Path(current_app.config['user_dir']) / path / patient_name
        if not patient_path.exists():
            return jsonify({"code": 400, "message": "患者文件夹不存在", "data": ""})

        # 获取目标患者图片文件信息
        image_list = get_child_file_list(patient_path, file_types=['.jpg', '.jpeg', '.png'])
        image_info_list = []

        # 获取图片的特征信息
        image_feature_excel_path = Path(patient_path) / f"{patient_name}.xlsx"
        image_feature_info = get_image_features(image_feature_excel_path)
        # 组装数据
        for image_name in image_list:
            image_info_list.append({
                'name': image_name,
                'url': f"{current_app.config['resource_url']}/static/User/{path}/{patient_name}/{image_name}",
                'isMark': image_name in image_feature_info.keys(),
            })
        return jsonify({"code": 200, "message": "获取患者信息数据成功", "data": {
            "imageList": image_info_list,
            "diagnosisResult": image_feature_info['diagnosisResult'],
            # "isMark": image_feature_info['isMark']
        }})


class GetImageFeatureResource(Resource):
    """
    获取图片的特征信息
    """
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('path', type=str, required=True, help='path is required')
        parser.add_argument('patientName', type=str, required=True, help='patientName is required')
        parser.add_argument('imageName', type=str, required=True, help='imageName is required')
        data = parser.parse_args()

        patient_path = Path(current_app.config['user_dir'], get_real_path(data['path'], ",")) / data['patientName']
        image_name = data['imageName']
        image_feature_excel_path = Path(patient_path) / f"{data['patientName']}.xlsx"
        if not image_feature_excel_path.exists():
            return jsonify({"code": 200, "message": "图片特征文件不存在", "data": []})
        image_path = Path(patient_path) / image_name

        feature = get_image_feature(image_path, image_feature_excel_path)
        data = []
        if feature.get(image_name):
            data = feature[image_name]
        return jsonify({"code": 200, "message": "获取图片特征成功", "data": data})
